home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / UUPC11QS.ARJ / SECURITY.C < prev    next >
C/C++ Source or Header  |  1991-11-21  |  33KB  |  835 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    s e c u r i t y . c                                             */
  3. /*                                                                    */
  4. /*    Security routines for UUPC/extended                             */
  5. /*                                                                    */
  6. /*    Copyright (c) 1991, Andrew H. Derbyshire                        */
  7. /*    See README.PRN for additional copyrights and restrictions       */
  8. /*--------------------------------------------------------------------*/
  9.  
  10. /*--------------------------------------------------------------------*/
  11. /*                        System include files                        */
  12. /*--------------------------------------------------------------------*/
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <direct.h>
  18. #include <time.h>
  19.  
  20. /*--------------------------------------------------------------------*/
  21. /*                    UUPC/extended include files                     */
  22. /*--------------------------------------------------------------------*/
  23.  
  24. #include "lib.h"
  25. #include "hostable.h"
  26. #include "security.h"
  27. #include "usertabl.h"
  28. #include "expath.h"
  29. #include "hlib.h"
  30.  
  31. /*--------------------------------------------------------------------*/
  32. /*                           Local defines                            */
  33. /*--------------------------------------------------------------------*/
  34.  
  35. #define free( x )
  36. #define ANY_HOST     "OTHER"
  37. #define ANY_COMMAND  "ALL"
  38.  
  39. static boolean InitEntry( char *buf, const char *fname);
  40.  
  41. static size_t InitDir( char *directories,
  42.          const REMOTE_ACCESS access,
  43.          const boolean grant,
  44.          struct HostSecurity *anchor,
  45.          size_t max_elements );
  46.  
  47. int dircmp( const void *a , const void *b );
  48.  
  49. /*--------------------------------------------------------------------*/
  50. /*                          Global varables                           */
  51. /*--------------------------------------------------------------------*/
  52.  
  53. struct HostSecurity *securep = NULL;
  54. static struct HostSecurity *default_security = NULL;
  55. static char drive[] = "C:";
  56.  
  57. currentfile();
  58.  
  59. /*--------------------------------------------------------------------*/
  60. /*    L o a d S e c u r i t y                                         */
  61. /*                                                                    */
  62. /*    Initialize security processing; returns TRUE if security        */
  63. /*    initialized, otherewise FALSE                                   */
  64. /*--------------------------------------------------------------------*/
  65.  
  66. boolean LoadSecurity( void )
  67. {
  68.    char fname[FILENAME_MAX];
  69.    char buffer[BUFSIZ*4];     /* Allows around 2K for the data       */
  70.    struct HostTable *hostp;
  71.    FILE *stream;
  72.  
  73. /*--------------------------------------------------------------------*/
  74. /*      Generate a filename for the permissions file and open it      */
  75. /*--------------------------------------------------------------------*/
  76.  
  77.    mkfilename(fname, confdir, PERMISSIONS);
  78.    stream  = FOPEN( fname, "r", TEXT);
  79.  
  80.    if ( stream == NULL )      /* Did the file open?                  */
  81.    {                          /* No --> Report failure to caller     */
  82.       printerr( fname );
  83.       return FALSE;
  84.    } /* ( stream == NULL ) */
  85.  
  86. /*--------------------------------------------------------------------*/
  87. /*              Get current drive for normalizing names               */
  88. /*--------------------------------------------------------------------*/
  89.  
  90.    getcwd( buffer, sizeof buffer );
  91.    *drive = *buffer;
  92.  
  93. /*--------------------------------------------------------------------*/
  94. /*               Begin processing the PERMISSIONS file                */
  95. /*--------------------------------------------------------------------*/
  96.  
  97.    while ( !feof( stream ) )
  98.    {
  99.       char *next = buffer;
  100.  
  101. /*--------------------------------------------------------------------*/
  102. /*                Build up the buffer to be processed                 */
  103. /*--------------------------------------------------------------------*/
  104.  
  105.       *next = '\0';
  106.       while( fgets( next, sizeof buffer - strlen(next), stream ) != NULL)
  107.       {
  108.          if ((*next == '#') || (*next == '\n'))
  109.          {
  110.             *next = '\0';
  111.             continue;
  112.          }
  113.  
  114.          next = next + strlen( next ) - 1;
  115.          if (*next == '\n')
  116.             *next-- = '\0';
  117.          else if (!feof( stream ))  /* Did we hit EOF?               */
  118.          {                    /* No --> Presume the buffer overflowed*/
  119.             printmsg(0,"LoadSecurity: buffer overflow while reading %s",
  120.              fname);
  121.             fclose( stream );
  122.             return FALSE;
  123.          }
  124.  
  125.          if (*next == '\\')
  126.             *next = '\0';
  127.          else
  128.             break;
  129.       } /* while( fgets( next, sizeof available, stream )) != NULL)) */
  130.  
  131. /*--------------------------------------------------------------------*/
  132. /*            Done read the data; verify we had no errors             */
  133. /*--------------------------------------------------------------------*/
  134.  
  135.       if (ferror( stream ))
  136.       {
  137.          printerr( fname );
  138.          clearerr( stream );
  139.          return FALSE;
  140.       } /* if */
  141.  
  142. /*--------------------------------------------------------------------*/
  143. /*              Build entries for one permissions entry               */
  144. /*--------------------------------------------------------------------*/
  145.  
  146.       printmsg(10,"Buffer is \"%s\"", buffer );
  147.       if ((*next != '\0') && !InitEntry( buffer , fname))
  148.       {
  149.          fclose( stream );
  150.          return FALSE;
  151.       }
  152.  
  153.    } /* while ( !feof( stream ) ) */
  154.  
  155. /*--------------------------------------------------------------------*/
  156. /*                    Initialize local host entry                     */
  157. /*--------------------------------------------------------------------*/
  158.  
  159.    hostp = checkname( nodename );
  160.    if ( hostp == NULL )
  161.       panic();
  162.    hostp->hsecure = malloc( sizeof *hostp->hsecure );
  163.    checkref( hostp->hsecure );
  164.    memset( hostp->hsecure , '\0', sizeof *hostp->hsecure);
  165.                               /* Clear pointers                      */
  166.    hostp->hsecure->local = TRUE;
  167.  
  168. /*--------------------------------------------------------------------*/
  169. /*                          Return to caller                          */
  170. /*--------------------------------------------------------------------*/
  171.  
  172.    return TRUE;
  173.  
  174. } /* LoadSecurity */
  175.  
  176. /*--------------------------------------------------------------------*/
  177. /*    I n i t i a l i z e E n t r y                                   */
  178. /*                                                                    */
  179. /*    Initialize a single permissions file entry                      */
  180. /*--------------------------------------------------------------------*/
  181.  
  182. static boolean InitEntry( char *buf, const char *fname)
  183. {
  184.  
  185. /*--------------------------------------------------------------------*/
  186. /*                      Configuration variables                       */
  187. /*--------------------------------------------------------------------*/
  188.  
  189.   static char *myname, *validate, *commands;
  190.  
  191.   static char *callback, *xpubdir, *machine, *noread, *nowrite;
  192.   static char *request, *read, *sendfiles,  *write, *logname;
  193.  
  194.   static CONFIGTABLE securetable[] = {
  195.      "callback",      &callback,     B_TOKEN  | B_UUIO,
  196.      "commands",      &commands,     B_CLIST  | B_UUIO,
  197.      "logname",       &logname,      B_TOKEN  | B_UUIO,
  198.      "machine",       &machine,      B_TOKEN  | B_UUIO,
  199.      "myname",        &myname,       B_TOKEN  | B_UUIO,
  200.      "pubdir",        &xpubdir,      B_TOKEN  | B_UUIO,
  201.      "noread",        &noread,       B_TOKEN  | B_UUIO,
  202.      "nowrite",       &nowrite,      B_TOKEN  | B_UUIO,
  203.      "read",          &read,         B_TOKEN  | B_UUIO,
  204.      "request",       &request,      B_TOKEN  | B_UUIO,
  205.      "sendfiles",     &sendfiles,    B_TOKEN  | B_UUIO,
  206.      "validate",      &validate,     B_CLIST  | B_UUIO,
  207.      "write",         &write,        B_TOKEN  | B_UUIO,
  208.      nil(char)
  209. }; /* securetable */
  210.  
  211.    struct HostSecurity *anchor = malloc( sizeof *anchor );
  212.  
  213. /*--------------------------------------------------------------------*/
  214. /*                  Default list of allowed commands                  */
  215. /*--------------------------------------------------------------------*/
  216.  
  217.    static char *command_list[] = { "rmail", "rnews" , NULL } ;
  218.  
  219. /*--------------------------------------------------------------------*/
  220. /*                          Other variables                           */
  221. /*--------------------------------------------------------------------*/
  222.  
  223.    boolean success = TRUE;
  224.    CONFIGTABLE *tptr;
  225.    char *token = buf;
  226.    char *parameter;
  227.    struct UserTable *userp;
  228.    struct HostTable *hostp;
  229.    size_t max_elements = 16;
  230.  
  231. /*--------------------------------------------------------------------*/
  232. /*                 Initialize the security structure                  */
  233. /*--------------------------------------------------------------------*/
  234.  
  235.    checkref( anchor );
  236.    memset( anchor , '\0', sizeof *anchor); /* Clear pointers         */
  237.  
  238. /*--------------------------------------------------------------------*/
  239. /*                        Initialize the table                        */
  240. /*--------------------------------------------------------------------*/
  241.  
  242.    for (tptr = securetable; tptr->sym != nil(char); tptr++)
  243.       if (tptr->bits & (B_TOKEN | B_STRING | B_LIST| B_CLIST))
  244.          *(tptr->loc) = nil(char);
  245.  
  246. /*--------------------------------------------------------------------*/
  247. /*                 Parse the information in the table                 */
  248. /*--------------------------------------------------------------------*/
  249.  
  250.    while ( (parameter = strtok( token, WHITESPACE )) != NULL)
  251.    {
  252.       token = strtok( NULL, ""); /* Save for next pass               */
  253. #ifdef _DEBUG
  254.       printmsg(8,"InitEntry: Parameter is \"%s\"", parameter);
  255.       if ( token != NULL )
  256.          printmsg(10,"InitEntry: Buffer remaining is \"%s\"", token);
  257. #endif
  258.       if (!processconfig(parameter, SYSTEM_CONFIG,B_UUIO,securetable,NULL))
  259.       {
  260.          printmsg(0,
  261.           "Unknown keyword \"%s\" in %s ignored",parameter, fname);
  262.          success = FALSE;
  263.       } /* if */
  264.    } /* while ( (parameter = strtok( token, WHITESPACE )) != NULL) */
  265.  
  266.    anchor->commands = (char **) commands;
  267.    anchor->validate = (char **) validate;
  268.  
  269. /*--------------------------------------------------------------------*/
  270. /*    Now we have the data procesed by keyword, break it down more    */
  271. /*--------------------------------------------------------------------*/
  272.  
  273.    if ((logname == NULL) && (machine == NULL))
  274.    {
  275.       printmsg(0,"InitEntry: No machine or logname given in %s",
  276.                   fname );
  277.       success = FALSE;
  278.    } /* if ((logname == NULL) && (machine == NULL)) */
  279.  
  280. /*--------------------------------------------------------------------*/
  281. /*                        Handle a login name                         */
  282. /*--------------------------------------------------------------------*/
  283.  
  284.    if (logname != NULL)
  285.    {
  286.       printmsg(10,"InitEntry: Processing logname=%s",logname );
  287.       userp = checkuser( logname );
  288.       if ( userp == BADUSER )
  289.       {
  290.          printmsg(0,"InitEntry: Invalid user id in %s, LOGNAME=%s",
  291.                      fname, logname );
  292.          success = FALSE;
  293.       } /* if ( userp == BADUSER ) */
  294.       else if (userp->hsecure == NULL)
  295.          userp->hsecure = anchor;
  296.       else {
  297.          printmsg(0,"InitEntry: Duplicate user id in %s, LOGNAME=%s",
  298.                      fname, logname );
  299.          success = FALSE;
  300.       } /* else */
  301.    } /* if (logname != NULL) */
  302.  
  303. /*--------------------------------------------------------------------*/
  304. /*                        Handle machine names                        */
  305. /*--------------------------------------------------------------------*/
  306.  
  307.    token = machine;
  308.    while( token != NULL )
  309.    {
  310.       char *host = strtok( token, ":");
  311.       printmsg(10,"InitEntry: Processing machine=%s", host );
  312.  
  313.       token = strtok( NULL, "");
  314.       if ( equal( host , ANY_HOST ) )
  315.       {
  316.          if ( default_security == NULL )
  317.             default_security = anchor;
  318.          else {
  319.             printmsg(0,"InitEntry: \
  320. Multiple MACHINE entries in %s which specify OTHER",fname);
  321.             success = FALSE;
  322.          } /* else */
  323.       } /* if ( equal( host , ANY_HOST ) ) */
  324.       else {
  325.          hostp = checkreal( host );
  326.          if ( hostp == BADUSER )
  327.          {
  328.             printmsg(0,"InitEntry: Invalid host id in %s, MACHINE=%s",
  329.                         fname, host );
  330.             success = FALSE;
  331.          } /* if ( hostp == BADUSER ) */
  332.          else if (hostp->hsecure == NULL)
  333.             hostp->hsecure = anchor;
  334.          else {
  335.             printmsg(0,"InitEntry: Duplicate host id in %s, MACHINE=%s",
  336.                         fname, token );
  337.             success = FALSE;
  338.          } /* else */
  339.       } /* else */
  340.    } /* while( token != NULL ) */
  341.  
  342.    if ( machine != NULL )
  343.       free( machine );
  344.  
  345. /*--------------------------------------------------------------------*/
  346. /*                          Handle CALLBACK                           */
  347. /*--------------------------------------------------------------------*/
  348.  
  349.    if ( callback != NULL )
  350.    {
  351.       if (equal(strlwr(callback),"no"))
  352.          anchor->callback = FALSE;
  353.       else if (equal(callback,"yes"))
  354.          anchor->callback = TRUE;
  355.       else {
  356.          printmsg(0,"InitEntry: Invalid value in %s, CALLBACK=%s",
  357.                      fname, callback );
  358.          success = FALSE;
  359.       } /* else */
  360.       free( callback );
  361.    } /* if ( callback != NULL ) */
  362.  
  363. /*--------------------------------------------------------------------*/
  364. /*                          Handle REQUEST                            */
  365. /*--------------------------------------------------------------------*/
  366.  
  367.    if ( request != NULL )
  368.    {
  369.       if (equal(strlwr(request),"no"))
  370.          anchor->request = FALSE;
  371.       else if (equal(request,"yes"))
  372.          anchor->request = TRUE;
  373.       else {
  374.          printmsg(0,"InitEntry: Invalid value in %s, REQUEST=%s",
  375.                      fname, request );
  376.          success = FALSE;
  377.       } /* else */
  378.  
  379.       free( request );
  380.    } /* if ( request != NULL ) */
  381.  
  382. /*--------------------------------------------------------------------*/
  383. /*                          Handle SENDFILES                          */
  384. /*--------------------------------------------------------------------*/
  385.  
  386.    if ( sendfiles != NULL)
  387.    {
  388.       if (equal(strlwr(sendfiles),"call"))
  389.          anchor->sendfiles = FALSE;
  390.       else if (equal(sendfiles,"yes"))
  391.          anchor->sendfiles = TRUE;
  392.       else {
  393.          printmsg(0,"InitEntry: Invalid value in %s, SENDFILES=%s",
  394.                      fname, sendfiles );
  395.          success = FALSE;
  396.       } /* else */
  397.       free( sendfiles );
  398.    } /* if */
  399.  
  400. /*--------------------------------------------------------------------*/
  401. /*                          handle commands                           */
  402. /*--------------------------------------------------------------------*/
  403.  
  404.    if ( anchor->commands == NULL )
  405.       anchor->commands = command_list;
  406.  
  407. /*--------------------------------------------------------------------*/
  408. /*                 Handle local system name aliasing                  */
  409. /*--------------------------------------------------------------------*/
  410.  
  411.    if (myname == NULL)
  412.       anchor->myname = nodename;
  413.    else
  414.       anchor->myname = myname;
  415.  
  416. /*--------------------------------------------------------------------*/
  417. /*                      Directory processing                          */
  418. /*--------------------------------------------------------------------*/
  419.  
  420.    anchor->dirlist = malloc( sizeof anchor->dirlist[0] * max_elements );
  421.    checkref( anchor->dirlist );
  422.  
  423.    max_elements = InitDir( read,    ALLOW_READ,  TRUE,  anchor,
  424.             max_elements );
  425.    free( read );
  426.    max_elements = InitDir( noread,  ALLOW_READ,  FALSE, anchor,
  427.             max_elements );
  428.    free( noread );
  429.    max_elements = InitDir( write,   ALLOW_WRITE, TRUE,  anchor,
  430.             max_elements );
  431.    free( write );
  432.    max_elements = InitDir( nowrite, ALLOW_WRITE, FALSE, anchor,
  433.                            max_elements );
  434.    free( nowrite );
  435.  
  436. /*--------------------------------------------------------------------*/
  437. /*                 Provide a default public directory                 */
  438. /*--------------------------------------------------------------------*/
  439.  
  440.    if (xpubdir == NULL)
  441.        anchor->pubdir = pubdir;
  442.    else
  443.        anchor->pubdir = xpubdir;
  444.  
  445. /*--------------------------------------------------------------------*/
  446. /*    If no explicit directories given, give them access to pubdir    */
  447. /*--------------------------------------------------------------------*/
  448.  
  449.    if ( anchor->dirsize == 0)
  450.    {
  451.       max_elements = InitDir( anchor->pubdir, ALLOW_READ, TRUE,
  452.                               anchor, max_elements );
  453.       max_elements = InitDir( anchor->pubdir, ALLOW_WRITE, TRUE,
  454.                               anchor, max_elements );
  455.    }
  456.  
  457.    if ( max_elements == 0 )
  458.       success = FALSE;
  459.    else {
  460.       size_t subscript;
  461.       anchor->dirlist = realloc( anchor->dirlist,
  462.                                  anchor->dirsize * sizeof anchor->dirlist[0]);
  463.       checkref( anchor->dirlist );
  464.       qsort(anchor->dirlist, anchor->dirsize, sizeof(anchor->dirlist[0]),
  465.                dircmp);
  466.       if ( debuglevel > 4 )
  467.       for ( subscript = 0; subscript < anchor->dirsize; subscript++ )
  468.          printmsg(4, "InitEntry: dirlist[%d] %s\t%s\t%s",
  469.                   subscript,
  470.                   anchor->dirlist[subscript].grant ? "grant" : "deny" ,
  471.                   anchor->dirlist[subscript].priv == ALLOW_WRITE ?
  472.                            "WRITE" : "READ" ,
  473.                   anchor->dirlist[subscript].path );
  474.    } /* else */
  475.  
  476. /*--------------------------------------------------------------------*/
  477. /*                          Return to caller                          */
  478. /*--------------------------------------------------------------------*/
  479.  
  480.    return success;
  481.  
  482. } /* InitEntry */
  483.  
  484. /*--------------------------------------------------------------------*/
  485. /*    I n i t D i r                                                   */
  486. /*                                                                    */
  487. /*    Initialize security table directory entries                     */
  488. /*--------------------------------------------------------------------*/
  489.  
  490. static size_t InitDir( char *directories,
  491.          const REMOTE_ACCESS access,
  492.          const boolean grant,
  493.          struct HostSecurity *anchor,
  494.          size_t max_elements )
  495. {
  496.    char *field = directories;
  497.    char *token = directories;
  498.    char *column;
  499.    size_t subscript;
  500.  
  501. /*--------------------------------------------------------------------*/
  502. /*    Don't process data if no input or we previously had an error    */
  503. /*--------------------------------------------------------------------*/
  504.  
  505.    if ( (directories == NULL ) || ( max_elements == 0) )
  506.       return max_elements;
  507.  
  508. /*--------------------------------------------------------------------*/
  509. /*              Begin loop to process names in the path               */
  510. /*--------------------------------------------------------------------*/
  511.  
  512.    while ( (token = NextField( field )) != NULL)
  513.    {
  514.       if ( anchor->dirsize == max_elements )
  515.       {
  516.          max_elements = max_elements * 2;
  517.          anchor->dirlist = realloc( anchor->dirlist,
  518.                 sizeof anchor->dirlist[0] * max_elements );
  519.          checkref( anchor->dirlist );
  520.       }
  521.  
  522. /*--------------------------------------------------------------------*/
  523. /*                      Normalize directory name                      */
  524. /*--------------------------------------------------------------------*/
  525.  
  526.       if ( token[1] == ':' )
  527.          field = strdup( token );
  528.       else {
  529.          char path[FILENAME_MAX];
  530.  
  531.          strcpy( path , token );
  532.          expand_path( path, ".", pubdir , NULL);   /* Explode user ids  */
  533.          if ( expand_path( path, ".", pubdir , NULL) == NULL )
  534.          {
  535.             printmsg(0,"InitDir: Path \"%s\" is invalid.",token);
  536.             return 0;            /* Path is invalid, give up         */
  537.          }
  538.          else if ( path[1] == ':' )
  539.             field = strdup( path );
  540.          else {
  541.             column = malloc( strlen( path ) + sizeof drive );
  542.             checkref( column );
  543.             field = strcat( strcpy( column , drive ), path );
  544.          } /* else */
  545.       } /* else */
  546.  
  547.       column = strlwr( field );
  548.       while( (column = strchr( column , '\\')) != NULL)
  549.          *column++ = '/';     /* Backslashes to slashes              */
  550.  
  551.       if ( field[ strlen( field ) - 1 ] == '/')
  552.          field[ strlen( field ) - 1 ] = '\0';   /* Drop trailing slash */
  553.  
  554. /*--------------------------------------------------------------------*/
  555. /*           Verify this directory not already in the list            */
  556. /*--------------------------------------------------------------------*/
  557.  
  558.       for (subscript = 0; subscript < anchor->dirsize ; subscript++)
  559.       {
  560.          if ( (access == anchor->dirlist[subscript].priv) &&
  561.               equali( field, anchor->dirlist[subscript].path))
  562.          {
  563.             printmsg(0,"InitDir: Duplicate directory %s/", field);
  564.             return 0;
  565.          } /* if */
  566.       } /* for */
  567.  
  568. /*--------------------------------------------------------------------*/
  569. /*            No conflict, add this directory to the list             */
  570. /*--------------------------------------------------------------------*/
  571.  
  572.       printmsg(10,"InitDir: Adding \"%s\" as \"%s\"", token , field);
  573.       anchor->dirlist[subscript].path  = field;
  574.       anchor->dirlist[subscript].priv  = access;
  575.       anchor->dirlist[subscript].grant = grant;
  576.       anchor->dirsize++;
  577.  
  578.       field = NULL;           /* Look at next field next pass        */
  579.  
  580.    } /* while ( (field = NextField( field )) != NULL) */
  581.  
  582. /*--------------------------------------------------------------------*/
  583. /*                          Return to caller                          */
  584. /*--------------------------------------------------------------------*/
  585.  
  586.    return max_elements;
  587. } /* InitDir */
  588.  
  589. /*--------------------------------------------------------------------*/
  590. /*    d i r c m p                                                     */
  591. /*                                                                    */
  592. /*                                                                    */
  593. /*    Compares two directory structures for sorting                   */
  594. /*--------------------------------------------------------------------*/
  595.  
  596. int dircmp( const void *a , const void *b )
  597. {
  598.    struct DIRLIST *x = (struct DIRLIST*) a;
  599.    struct DIRLIST *y = (struct DIRLIST*) b;
  600.  
  601.    int result = strcmp(x->path, y->path);
  602.  
  603.    if (result == 0)
  604.       result = ( x->priv < y->priv ) ? -1 : 1;
  605.  
  606.    return result;
  607. }  /*dircmp*/
  608.  
  609. /*--------------------------------------------------------------------*/
  610. /*    V a l i d a t e H o s t                                         */
  611. /*                                                                    */
  612. /*    Determine that a host is allowed for a specific login           */
  613. /*--------------------------------------------------------------------*/
  614.  
  615. boolean ValidateHost( const char *host )
  616. {
  617.    char **target;
  618.  
  619. /*--------------------------------------------------------------------*/
  620. /*      If this host has no security profile, reject the access       */
  621. /*--------------------------------------------------------------------*/
  622.  
  623.    if ( securep == NULL )
  624.       return FALSE;
  625.  
  626. /*--------------------------------------------------------------------*/
  627. /*            If we allow any host on this user id, use it            */
  628. /*--------------------------------------------------------------------*/
  629.  
  630.    target = securep->validate;
  631.    if ( target == NULL )
  632.       return TRUE;
  633.  
  634. /*--------------------------------------------------------------------*/
  635. /*          Determine if this host is allowed for this login          */
  636. /*--------------------------------------------------------------------*/
  637.  
  638.    while (*target != NULL)
  639.    {
  640.       if ( equal(*target++, host ))
  641.          return TRUE;
  642.    } /* (*target != NULL) */
  643.  
  644. /*--------------------------------------------------------------------*/
  645. /*                 We didn't find the host; reject it                 */
  646. /*--------------------------------------------------------------------*/
  647.  
  648.    return FALSE;
  649.  
  650. } /* ValidateHost */
  651.  
  652. /*--------------------------------------------------------------------*/
  653. /*    V a l i d a t e F i l e                                         */
  654. /*                                                                    */
  655. /*    Allow or reject access to a file by name                        */
  656. /*--------------------------------------------------------------------*/
  657.  
  658. boolean ValidateFile( const char *input,  /* Full path name          */
  659.                       const REMOTE_ACCESS needed )
  660. {
  661.    char path[FILENAME_MAX];
  662.    char *column;
  663.  
  664. /*--------------------------------------------------------------------*/
  665. /*                  Validate the length of the name                   */
  666. /*--------------------------------------------------------------------*/
  667.  
  668.    printmsg(5,"ValidateFile: Checking %s access for file \"%s\"",
  669.             (needed == ALLOW_WRITE) ? "WRITE" : "READ" , input);
  670.  
  671.    if ( strlen( input ) >= sizeof path)   /* Reject all invalid names*/
  672.    {
  673.       printmsg(0,"ValidateFile: Access rejected, name too long: %s",
  674.                  input);
  675.       return FALSE;
  676.    }
  677.  
  678. /*--------------------------------------------------------------------*/
  679. /*     Validate format of name; we don't allow parent directories     */
  680. /*--------------------------------------------------------------------*/
  681.  
  682.    if ( strstr( input, "..") )            /* Games with parent dir?  */
  683.    {
  684.       printmsg(0,"ValidateFile: Access rejected, name not normalized: %s",
  685.                  input);
  686.       return FALSE;
  687.    }
  688.  
  689. /*--------------------------------------------------------------------*/
  690. /*                Validate the security table is okay                 */
  691. /*--------------------------------------------------------------------*/
  692.  
  693.    if ( securep == NULL )
  694.       panic();
  695.  
  696. /*--------------------------------------------------------------------*/
  697. /*                        Handle local system                         */
  698. /*--------------------------------------------------------------------*/
  699.  
  700.    if ( securep->local )      /* Local system?                       */
  701.       return TRUE;            /* Yes --> Bless the request           */
  702.  
  703. /*--------------------------------------------------------------------*/
  704. /*       Determine if the user is allowed to perform anything!        */
  705. /*--------------------------------------------------------------------*/
  706.  
  707.    if (!securep->request)
  708.    {
  709.       printmsg(0,"ValidateFile: access rejected, REQUEST not enabled in permissions file");
  710.       return FALSE;
  711.    }
  712.  
  713. /*--------------------------------------------------------------------*/
  714. /*                           Copy path name                           */
  715. /*--------------------------------------------------------------------*/
  716.  
  717.    if ( input[1] == ':' )
  718.       strcpy( path, input );
  719.    else
  720.       strcat( strcpy( path , drive ), input );
  721.    strlwr( path );
  722.  
  723. /*--------------------------------------------------------------------*/
  724. /*              Locate the best file match for the path               */
  725. /*--------------------------------------------------------------------*/
  726.  
  727.    while( (column = strrchr( path, '/')) != NULL )
  728.    {
  729.       int lower = 0;
  730.       int upper = securep->dirsize - 1;
  731.  
  732.       *column = '\0';
  733.       printmsg(10,"ValidateFile: Searching for %s", path);
  734.  
  735.       while( lower <= upper )
  736.       {
  737.          int midpoint = (lower + upper) / 2;
  738.          int hit = strcmp(path, securep->dirlist[midpoint].path);
  739.  
  740.          printmsg(10,"ValidateFile: Comparing %s and %s",
  741.                         path, securep->dirlist[midpoint].path);
  742.  
  743.          if ( hit == 0 )
  744.             hit = (int) needed - (int) securep->dirlist[midpoint].priv;
  745.  
  746.          if (hit > 0)
  747.             lower = midpoint + 1;
  748.          else if (hit < 0)
  749.             upper = midpoint - 1;
  750.          else {
  751.             printmsg( securep->dirlist[midpoint].grant ? 5 : 0 ,
  752.                      "ValidateFile: Found path \"%s\", access %s to \"%s\"",
  753.                      securep->dirlist[midpoint].path,
  754.                      securep->dirlist[midpoint].grant ?
  755.                                     "granted" : "denied", input);
  756.             return securep->dirlist[midpoint].grant;
  757.          }
  758.       } /* while( lower <= upper ) */
  759.    } /* while( (column = strrchr( path, '/')) != NULL ) */
  760.  
  761. /*--------------------------------------------------------------------*/
  762. /*          We didn't find the file; reject all access to it          */
  763. /*--------------------------------------------------------------------*/
  764.  
  765.    printmsg(0,"ValidateFile: No access definition found for \
  766. \"%s\", access denied",
  767.             input);
  768.    return FALSE;
  769.  
  770. } /* ValidateFile */
  771.  
  772. /*--------------------------------------------------------------------*/
  773. /*    V a l i d a t e C o m m a n d                                   */
  774. /*                                                                    */
  775. /*    Determine if a command is allowed for a host                    */
  776. /*--------------------------------------------------------------------*/
  777.  
  778. boolean ValidateCommand( const char *command)
  779. {
  780.    char **p;
  781.  
  782. /*--------------------------------------------------------------------*/
  783. /*                Validate the security table is okay                 */
  784. /*--------------------------------------------------------------------*/
  785.  
  786.    if ( securep == NULL )
  787.       panic();
  788.  
  789. /*--------------------------------------------------------------------*/
  790. /*                        Handle local system                         */
  791. /*--------------------------------------------------------------------*/
  792.  
  793.    if ( securep->local )      /* Local system?                       */
  794.       return TRUE;            /* Yes --> Bless the request           */
  795.  
  796. /*--------------------------------------------------------------------*/
  797. /*     Loop through security command table looking for the target     */
  798. /*--------------------------------------------------------------------*/
  799.  
  800.    p = securep->commands;
  801.    while (*p != NULL)
  802.    {
  803.       if (equali(*p, command ) || equal(*p, ANY_COMMAND ))
  804.          return TRUE;
  805.       p++ ;
  806.    } /* while */
  807.  
  808. /*--------------------------------------------------------------------*/
  809. /*               We didn't find the command; reject it                */
  810. /*--------------------------------------------------------------------*/
  811.  
  812.    return FALSE;
  813.  
  814. } /* ValidateCommand */
  815.  
  816. /*--------------------------------------------------------------------*/
  817. /*    G e t S e c u r i t y                                           */
  818. /*                                                                    */
  819. /*    Return security structure for to use when calling out to        */
  820. /*    another system                                                  */
  821. /*--------------------------------------------------------------------*/
  822.  
  823. struct HostSecurity *GetSecurity( struct HostTable *hostp)
  824. {
  825.    if ((hostp->hsecure == NULL) && (default_security != NULL ))
  826.    {
  827.       printmsg(1,"GetSecurity: Using security for MACHINE=OTHER for \
  828. system \"%s\"", hostp->hostname );
  829.       hostp->hsecure = default_security;
  830.    } /* if  */
  831.  
  832.    return hostp->hsecure;
  833.  
  834. } /* GetSecurity */
  835.